package com.adv.ems.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.adv.ems.constants.EmsConst;
import com.adv.ems.db.entity.*;
import com.adv.ems.enums.CollectPointDataTypeEnum;
import com.adv.ems.enums.DateTypeEnum;
import com.adv.ems.enums.SubjectTypeEnum;
import com.adv.ems.manager.DepartmentInfoManager;
import com.adv.ems.manager.EnergyInfoManager;
import com.adv.ems.manager.InstituteInfoManager;
import com.adv.ems.model.dto.EnergyDataResultDTO;
import com.adv.ems.model.dto.QueryPointEnergyResultDTO;
import com.adv.ems.model.dto.TimeEnergyUseInfoDTO;
import com.adv.ems.model.dto.UserSubjectInfo;
import com.adv.ems.model.param.*;
import com.adv.ems.model.vo.*;
import com.adv.ems.service.IndexService;
import com.adv.ems.utils.EmsDateUtil;
import com.adv.ems.utils.EmsUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class IndexServiceImpl extends BaseServiceImpl implements IndexService {
    @Resource
    InstituteInfoManager instituteInfoManager;
    @Resource
    DepartmentInfoManager departmentInfoManager;
    @Resource
    EnergyInfoManager energyInfoManager;

    @Override
    public IndexEnergyMapSubjectVO mapSubjectList(IndexEnergyMapSubjectParam param, String acceptLanguage) {
        UserSubjectInfo userSubjectInfo = rebuildUserSubjectInfo(param.getSubjectType(), param.getSubjectId());
        IndexEnergyMapSubjectVO vo = new IndexEnergyMapSubjectVO();
        Date from = DateUtil.beginOfDay(new Date());
        DateTypeEnum source = DateTypeEnum.day;
        if (DateTypeEnum.month.equals(param.getDateType())) {
            from = DateUtil.beginOfMonth(new Date());
            source = DateTypeEnum.month;
        }else if (DateTypeEnum.year.equals(param.getDateType())) {
            from = DateUtil.beginOfYear(new Date());
            source = DateTypeEnum.year;
        }
        if (CollectionUtil.isNotEmpty(userSubjectInfo.getInstitute())) {
            Long id = userSubjectInfo.getInstitute().get(0);
            List<IndexEnergyMapSubjectVO.Info> list = getByInstitutionId(source, id, param.getEnergyId(), from, acceptLanguage);
            vo.getList().addAll(list);
        }else if (CollectionUtil.isNotEmpty(userSubjectInfo.getBuilding())){
            Long id = userSubjectInfo.getBuilding().get(0);
            List<IndexEnergyMapSubjectVO.Info> list = getByBuildingId(source, id, param.getEnergyId(), from, acceptLanguage);
            vo.getList().addAll(list);
        }else if (CollectionUtil.isNotEmpty(userSubjectInfo.getDepartment())){
            Long id = userSubjectInfo.getDepartment().get(0);
            IndexEnergyMapSubjectVO.Info obj = getByDepartmentId(source, id, param.getEnergyId(), from, acceptLanguage);
            vo.getList().add(obj);
        }
        return vo;
    }

    @Override
    public IndexEnergyInfoVO IndexEnergyInfoVO(String acceptLanguage) {
        Set<Long> energyIds = meterManager
                .getAllMap()
                .values()
                .stream()
                .map(MeterDO::getEnergyId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        List<IndexEnergyInfoVO.Info> list = energyInfoManager
                .getAllMap()
                .values()
                .stream()
                .filter(e -> energyIds.contains(e.getId()))
                .sorted(Comparator.comparing(EnergyInfoDO::getSort))
                .map(e -> new IndexEnergyInfoVO.Info(e, acceptLanguage))
                .collect(Collectors.toList());
        IndexEnergyInfoVO result = new IndexEnergyInfoVO();
        result.setList(list);
        return result;
    }

    @Override
    public IndexEnergyCalendarVO energyCalendar(IndexEnergyCalendarParam param, String acceptLanguage) {
        IndexEnergyCalendarVO result = new IndexEnergyCalendarVO();
        Date locateDate = StringUtils.hasLength(param.getMonth()) ? DateUtil.parseDate(param.getMonth()) : new Date();
        result.setMonth(DateUtil.formatDate(locateDate));
        result.setMonthInfo(DateUtil.format(locateDate, "yyyy年MM月"));
        List<Date> calendarDays = EmsDateUtil.getCalendarDays(locateDate);
        Date from = new Date(calendarDays.get(0).getTime() - Duration.ofDays(1).toMillis());
        Date end = calendarDays.get(calendarDays.size() - 1);

        UserSubjectInfo userSubjectInfo = rebuildUserSubjectInfo(param.getSubjectType(), param.getSubjectId());
        List<Long> pontIds = getPointIdsByUserSubjectInfo(userSubjectInfo, param.getEnergyId(), null, null, null);
        List<QueryPointEnergyResultDTO> list = getPointEnergy(DateTypeEnum.day, from, end, pontIds);
        Map<String, QueryPointEnergyResultDTO> groupDate = QueryPointEnergyResultDTO.groupByDate(list, param.getEnergyId(), DateTypeEnum.day, false).stream().collect(Collectors.toMap(d -> DateUtil.formatDate(d.getDate()), d -> d, (d1, d2) -> d2));

        while (from.getTime() <= end.getTime()) {
            String date = DateUtil.formatDate(from);
            QueryPointEnergyResultDTO orDefault = groupDate.getOrDefault(date, new QueryPointEnergyResultDTO());

            IndexEnergyCalendarVO.Info info = new IndexEnergyCalendarVO.Info();
            info.setDate(date);
            info.setDayOfMonth(DateUtil.dayOfMonth(from));
            info.setIncreaseRealValue(orDefault.getIncreaseRealValue());
            info.setIncreaseCashValue(orDefault.getIncreaseCashValue());
            info.setIncreaseStandValue(orDefault.getIncreaseStandValue());
            result.getList().add(info);
            from.setTime(from.getTime() + Duration.ofDays(1).toMillis());
        }
        Double lastVal = result.getList().get(0).getIncreaseStandValue();
        for (IndexEnergyCalendarVO.Info info: result.getList()) {
            if (info.getIncreaseStandValue() > lastVal) {
                info.setIncrease(1);
            }else if (info.getIncreaseStandValue() < lastVal) {
                info.setIncrease(-1);
            }else {
                info.setIncrease(0);
            }
        }
        result.getList().remove(0);
        return result;
    }

    @Override
    public IndexEnergyTimeTrendVO energyTimeTrend(IndexEnergyTimeTrendParam param, String acceptLanguage) {
        UserSubjectInfo userSubjectInfo = rebuildUserSubjectInfo(param.getSubjectType(), param.getSubjectId());
        List<Long> pontIds = getPointIdsByUserSubjectInfo(userSubjectInfo, param.getEnergyId(), param.getItemId(), param.getItemOneId(), param.getItemTwoId());
        Date from = DateUtil.parseDateTime(param.getFromDate());
        Date end = StringUtils.hasLength(param.getToDate()) ? DateUtil.parseDateTime(param.getToDate()) : new Date();
        EnergyDataResultDTO resultDTO = getAllPointEnergy(param.getToDateType(), from, end, pontIds);
        Map<Date, QueryPointEnergyResultDTO> groupDate = QueryPointEnergyResultDTO.groupByDate(resultDTO.getList(), param.getEnergyId(), param.getToDateType(), resultDTO.getProcess()).stream().collect(Collectors.toMap(QueryPointEnergyResultDTO::getDate, q -> q, (d1, d2) -> d2));
        IndexEnergyTimeTrendVO result = new IndexEnergyTimeTrendVO();
        while (from.getTime() <= end.getTime()) {
            String date = DateTypeEnum.hour.equals(param.getToDateType()) ? DateUtil.format(from, "dd日HH时"): DateUtil.format(from, "MM月dd日");
            QueryPointEnergyResultDTO orDefault = groupDate.getOrDefault(from, new QueryPointEnergyResultDTO());
            IndexEnergyTimeTrendVO.Info info = new IndexEnergyTimeTrendVO.Info();
            info.setTime(date);
            info.setIncreaseRealValue(orDefault.getIncreaseRealValue());
            info.setIncreaseCashValue(orDefault.getIncreaseCashValue());
            info.setIncreaseStandValue(orDefault.getIncreaseStandValue());
            result.getList().add(info);
            if (DateTypeEnum.hour.equals(param.getToDateType())) {
                from.setTime(from.getTime() + Duration.ofHours(1).toMillis());
            }else {
                from.setTime(from.getTime() + Duration.ofDays(1).toMillis());
            }
        }
        return result;
    }

    @Override
    public IndexCompareVO itemCompare(IndexCompareParam param, String acceptLanguage) {
        IndexCompareVO result = new IndexCompareVO();
        Date end = StringUtils.hasLength(param.getToDate()) ? DateUtil.parseDateTime(param.getToDate()) : new Date();
        Date from = StringUtils.hasLength(param.getFromDate()) ? DateUtil.parseDateTime(param.getFromDate()): DateUtil.beginOfYear(end);
        UserSubjectInfo userSubjectInfo = rebuildUserSubjectInfo(param.getSubjectType(), param.getSubjectId());
        List<Long> pontIds = getPointIdsByUserSubjectInfo(userSubjectInfo, param.getEnergyId(), param.getItemId(), null, null);
        List<QueryPointEnergyResultDTO> list = getPointEnergy(param.getDateType(), from, end, pontIds);
        Map<String, QueryPointEnergyResultDTO> data = QueryPointEnergyResultDTO.groupByNext(
                param.getEnergyId(),
                param.getItemId(),
                param.getItemOneId(),
                list,
                meterManager.getAllMap(),
                collectPointManager.getAllMap(),
                itemInfoManager.getAllMap(),
                itemOneInfoManager.getAllMap(),
                itemTwoInfoManager.getAllMap(),
                acceptLanguage);
        for (Map.Entry<String, QueryPointEnergyResultDTO> entry : data.entrySet()) {
            IndexCompareVO.Info info = new IndexCompareVO.Info();
            info.setName(entry.getKey());
            info.setIncreaseRealValue(entry.getValue().getIncreaseRealValue());
            info.setIncreaseCashValue(entry.getValue().getIncreaseCashValue());
            info.setIncreaseStandValue(entry.getValue().getIncreaseStandValue());
            result.getList().add(info);
        }
        return result;
    }

    @Override
    public IndexCompareVO energyCompare(IndexCompareParam param, String acceptLanguage) {
        Date end = StringUtils.hasLength(param.getToDate()) ? DateUtil.parseDateTime(param.getToDate()) : new Date();
        Date from = StringUtils.hasLength(param.getFromDate()) ? DateUtil.parseDateTime(param.getFromDate()): DateUtil.beginOfYear(end);

        UserSubjectInfo userSubjectInfo = rebuildUserSubjectInfo(param.getSubjectType(), param.getSubjectId());
        List<Long> pontIds = getPointIdsByUserSubjectInfo(userSubjectInfo, param.getEnergyId(), null, null, null);
        List<QueryPointEnergyResultDTO> list = getPointEnergy(param.getDateType(), from, end, pontIds);
        Map<String, QueryPointEnergyResultDTO> data = QueryPointEnergyResultDTO.groupByEnergyName(list, collectPointManager.getAllMap(), meterManager.getAllMap(), energyInfoManager.getAllMap(), acceptLanguage);
        IndexCompareVO result = new IndexCompareVO();
        for (Map.Entry<String, QueryPointEnergyResultDTO> entry : data.entrySet()) {
            IndexCompareVO.Info info = new IndexCompareVO.Info();
            info.setName(entry.getKey());
            info.setIncreaseRealValue(entry.getValue().getIncreaseRealValue());
            info.setIncreaseCashValue(entry.getValue().getIncreaseCashValue());
            info.setIncreaseStandValue(entry.getValue().getIncreaseStandValue());
            result.getList().add(info);
        }
        return result;
    }

    @Override
    public IndexEnergyYearSummarizeVO energyYearSummarize(IndexEnergyYearSummarizeParam param, String acceptLanguage) {
        UserSubjectInfo userSubjectInfo = rebuildUserSubjectInfo(param.getSubjectType(), param.getSubjectId());
        List<Long> pontIds = getPointIdsByUserSubjectInfo(userSubjectInfo, null, null, null, null);
        Set<String> energyNameList = getEnergyNameList(pontIds, acceptLanguage);
        //今年
        Date endNow = new Date();
        Date fromNow = DateUtil.beginOfYear(new Date());
        List<QueryPointEnergyResultDTO> nowList = getPointEnergy(DateTypeEnum.year, fromNow, endNow, pontIds);
        Map<String, QueryPointEnergyResultDTO> nowGroupByEnergy = QueryPointEnergyResultDTO.groupByEnergyName(nowList, collectPointManager.getAllMap(), meterManager.getAllMap(), energyInfoManager.getAllMap(), acceptLanguage);
        //去年
        Date endLast = new Date(endNow.getTime() - Duration.ofDays(365).toMillis());
        Date fromLast = DateUtil.beginOfYear(endLast);
        List<QueryPointEnergyResultDTO> lastList = getPointEnergy(DateTypeEnum.year, fromLast, endLast, pontIds);
        Map<String, QueryPointEnergyResultDTO> lastGroupByEnergy = QueryPointEnergyResultDTO.groupByEnergyName(lastList, collectPointManager.getAllMap(), meterManager.getAllMap(), energyInfoManager.getAllMap(), acceptLanguage);
        IndexEnergyYearSummarizeVO result = new IndexEnergyYearSummarizeVO();

        for (String energyName : energyNameList) {
            List<EnergyInfoDO> energyInfos = energyInfoManager
                    .getAllMap()
                    .values()
                    .stream().filter(e -> EmsUtil.multilingual(e.getNameInfo(), acceptLanguage).equals(energyName)).collect(Collectors.toList());
            QueryPointEnergyResultDTO nowData = nowGroupByEnergy.get(energyName);
            QueryPointEnergyResultDTO lastData = lastGroupByEnergy.get(energyName);
            IndexEnergyYearSummarizeVO.Info info = new IndexEnergyYearSummarizeVO.Info();
            result.getList().add(info);
            info.setEnergyName(energyName);
            if (nowData == null) {
                info.setCompareToLast("无数据");
                continue;
            }
            Double nowRealValue = nowData.getIncreaseRealValue();
            Double lastRealValue = lastData == null ? 0D : lastData.getIncreaseRealValue();
            info.setUnit(energyInfos.isEmpty() ? "": energyInfos.get(0).getCumulateUnit());
            info.setIncreaseRealValue(nowRealValue);
            info.setIncreaseCashValue(nowData.getIncreaseCashValue());
            info.setIncreaseStandValue(nowData.getIncreaseStandValue());
            if (lastRealValue <= 0) {
                info.setCompareToLast("去年无数据");
            }else if (nowRealValue <= 0){
                info.setCompareToLast("今年无数据");
            }else {
                double v = (nowData.getIncreaseRealValue() - lastRealValue) * 100D / lastRealValue;
                if (v < 0) {
                    String format = EmsUtil.valueFormat(-1 * v);
                    info.setCompareToLast("下降" + format + "%");
                }else if (v > 0) {
                    String format = EmsUtil.valueFormat(v);
                    info.setCompareToLast("上升" + format + "%");
                }else {
                    info.setCompareToLast("持平");
                }
            }
        }
        result.setCashUnit(EmsConst.UNIT_CASH);
        result.setStandUnit(EmsConst.UNIT_STAND);
        return result;
    }

    @Override
    public IndexEnergyTimeCompareVO energyTimeCompare(IndexEnergyTimeCompareParam param, String acceptLanguage) {
        UserSubjectInfo userSubjectInfo = rebuildUserSubjectInfo(param.getSubjectType(), param.getSubjectId());
        List<Long> pontIds = getPointIdsByUserSubjectInfo(userSubjectInfo, null, null, null, null);
        Set<String> energyNameList = getEnergyNameList(pontIds, acceptLanguage);
        //今年
        Date endNow = new Date();
        Date fromNow;
        if (param.getAroundCompare()) {
            fromNow = DateUtil.beginOfMonth(new Date());
        }else {
            fromNow = DateUtil.beginOfYear(new Date());
        }
        List<QueryPointEnergyResultDTO> nowList = getPointEnergy(DateTypeEnum.month, fromNow, endNow, pontIds);
        Map<String, QueryPointEnergyResultDTO> nowGroupByEnergy = QueryPointEnergyResultDTO.groupByEnergyName(nowList, collectPointManager.getAllMap(), meterManager.getAllMap(), energyInfoManager.getAllMap(), acceptLanguage);
        //对比时间点
        Date endCompared;
        Date fromCompared;
        if (param.getAroundCompare()) {
            endCompared = DateUtil.offset(endNow, DateField.MONTH, -1);
            fromCompared = DateUtil.beginOfMonth(endCompared);
        }else {
            endCompared = DateUtil.offset(endNow, DateField.YEAR, -1);
            fromCompared = DateUtil.beginOfYear(endCompared);
        }
        List<QueryPointEnergyResultDTO> comparedList = getPointEnergy(DateTypeEnum.month, fromCompared, endCompared, pontIds);
        Map<String, QueryPointEnergyResultDTO> comparedGroupByEnergy = QueryPointEnergyResultDTO.groupByEnergyName(comparedList, collectPointManager.getAllMap(), meterManager.getAllMap(), energyInfoManager.getAllMap(), acceptLanguage);
        IndexEnergyTimeCompareVO result = new IndexEnergyTimeCompareVO();
        for (String energyName : energyNameList) {
            QueryPointEnergyResultDTO nowData = nowGroupByEnergy.getOrDefault(energyName, new QueryPointEnergyResultDTO());
            QueryPointEnergyResultDTO lastData = comparedGroupByEnergy.getOrDefault(energyName, new QueryPointEnergyResultDTO());
            IndexEnergyTimeCompareVO.Info info = new IndexEnergyTimeCompareVO.Info();
            info.setItemName(energyName);
            info.setIsAll(false);
            info.setIncreaseCashData(ListUtil.of(nowData.getIncreaseCashValue(), lastData.getIncreaseCashValue()));
            info.setIncreaseStandData(ListUtil.of(nowData.getIncreaseStandValue(), lastData.getIncreaseStandValue()));
            info.setIncreaseRealData(ListUtil.of(nowData.getIncreaseRealValue(), lastData.getIncreaseRealValue()));
            result.getList().add(info);
        }
        //所有
        QueryPointEnergyResultDTO nowAll = QueryPointEnergyResultDTO.sumAll(nowList);
        QueryPointEnergyResultDTO comparedAll = QueryPointEnergyResultDTO.sumAll(comparedList);
        IndexEnergyTimeCompareVO.Info info = new IndexEnergyTimeCompareVO.Info();
        info.setItemName("总量");
        info.setIncreaseCashData(ListUtil.of(0D, 0D));
        info.setIncreaseRealData(ListUtil.of(0D, 0D));
        info.setIncreaseStandData(ListUtil.of(nowAll.getIncreaseStandValue(), comparedAll.getIncreaseStandValue()));
        result.getList().add(info);
        return result;
    }

    private Set<String> getEnergyNameList(List<Long> pontIds, String acceptLanguage) {
        Set<String> energyNameList = new LinkedHashSet<>();
        for (Long pointId : pontIds) {
            CollectPointDO pointDO = collectPointManager.getAllMap().get(pointId);
            if (pointDO == null || pointDO.getMeterId() == null) {
                continue;
            }
            MeterDO meter = meterManager.getAllMap().get(pointDO.getMeterId());
            if (meter == null || meter.getEnergyId() == null) {
                continue;
            }
            EnergyInfoDO energyInfoDO = energyInfoManager.getAllMap().get(meter.getEnergyId());
            if (energyInfoDO == null) {
                continue;
            }
            energyNameList.add(EmsUtil.multilingual(energyInfoDO.getNameInfo(), acceptLanguage));
        }
        return energyNameList;
    }

    private UserSubjectInfo rebuildUserSubjectInfo(SubjectTypeEnum subjectType, Long subjectId) {
        UserDO currentUser = getCurrentUser();
        UserSubjectInfo userSubjectInfo;
        if (subjectId == null) {
            userSubjectInfo = getUserSubjectInfo(currentUser);
        }else {
            userSubjectInfo = new UserSubjectInfo();
            if (subjectType.equals(SubjectTypeEnum.BUILDING)) {
                userSubjectInfo.setBuilding(ListUtil.of(subjectId));
            }else if (subjectType.equals(SubjectTypeEnum.INSTITUTE)) {
                userSubjectInfo.setInstitute(ListUtil.of(subjectId));
            }else if (subjectType.equals(SubjectTypeEnum.DEPARTMENT)) {
                userSubjectInfo.setDepartment(ListUtil.of(subjectId));
            }else if (subjectType.equals(SubjectTypeEnum.METER)) {
                userSubjectInfo.setMeterIds(ListUtil.of(subjectId));
            }else if (subjectType.equals(SubjectTypeEnum.POINT)) {
                userSubjectInfo.setPointIds(ListUtil.of(subjectId));
            }else if (subjectType.equals(SubjectTypeEnum.DIAGRAM)) {
                userSubjectInfo.setDiagramIds(ListUtil.of(subjectId));
            }
        }
        return userSubjectInfo;
    }

    private IndexEnergyMapSubjectVO.Info getByDepartmentId(DateTypeEnum source, Long departmentId, Long energyId, Date from, String acceptLanguage) {
        DepartmentInfoDO department = departmentInfoManager.getAllMap().get(departmentId);
        IndexEnergyMapSubjectVO.Info info = new IndexEnergyMapSubjectVO.Info();
        if (StringUtils.hasLength(department.getSatelliteLocation())) {
            info.setLocation(EmsUtil.formatLocation(department.getSatelliteLocation()));
        }
        info.setName(EmsUtil.getNameInfo(department.getNameInfo(), acceptLanguage).getShortName());
        info.setSubjectId(department.getId());
        info.setSubjectType(SubjectTypeEnum.DEPARTMENT.name());
        List<Long> meterIds = getEnergyMeterIdsByDepartmentId(department.getId());
        List<Long> pointIds = getCumulatePointIds(meterIds, energyId, null, null, null);
        List<QueryPointEnergyResultDTO> energyData = getPointEnergy(source, from, new Date(), pointIds);
        TimeEnergyUseInfoDTO sum = TimeEnergyUseInfoDTO.sumAll(energyId, energyData);
        info.setUse(sum);
        return info;
    }

    private List<IndexEnergyMapSubjectVO.Info> getByBuildingId(DateTypeEnum source, Long buildingId, Long energyId, Date from, String acceptLanguage) {
        List<DepartmentInfoDO> departments = departmentInfoManager
                .getAllMap()
                .values()
                .stream()
                .filter(d -> buildingId.equals(d.getBuildingId()))
                .collect(Collectors.toList());
        List<IndexEnergyMapSubjectVO.Info> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(departments)) {
            for (DepartmentInfoDO department : departments) {
                IndexEnergyMapSubjectVO.Info info = new IndexEnergyMapSubjectVO.Info();
                if (StringUtils.hasLength(department.getSatelliteLocation())) {
                    info.setLocation(EmsUtil.formatLocation(department.getSatelliteLocation()));
                }
                info.setName(EmsUtil.getNameInfo(department.getNameInfo(), acceptLanguage).getShortName());
                info.setSubjectId(department.getId());
                info.setSubjectType(SubjectTypeEnum.DEPARTMENT.name());
                List<Long> meterIds = getEnergyMeterIdsByDepartmentId(department.getId());
                List<Long> pointIds = getCumulatePointIds(meterIds, energyId, null, null, null);
                List<QueryPointEnergyResultDTO> energyData = getPointEnergy(source, from, new Date(), pointIds);
                TimeEnergyUseInfoDTO sum = TimeEnergyUseInfoDTO.sumAll(energyId, energyData);
                info.setUse(sum);
                list.add(info);
            }
            list = list.stream().sorted().collect(Collectors.toList());
            return list;
        }
        BuildingInfoDO building = buildingInfoManager.getAllMap().get(buildingId);
        IndexEnergyMapSubjectVO.Info info = new IndexEnergyMapSubjectVO.Info();
        if (StringUtils.hasLength(building.getSatelliteLocation())) {
            info.setLocation(EmsUtil.formatLocation(building.getSatelliteLocation()));
        }
        info.setName(EmsUtil.getNameInfo(building.getNameInfo(), acceptLanguage).getShortName());
        info.setSubjectId(building.getId());
        info.setSubjectType(SubjectTypeEnum.BUILDING.name());
        List<Long> meterIds = getEnergyMeterIdsByBuildingId(building.getId());
        List<Long> pointIds = getCumulatePointIds(meterIds, energyId, null, null, null);
        List<QueryPointEnergyResultDTO> energyData = getPointEnergy(source, from, new Date(), pointIds);
        TimeEnergyUseInfoDTO sum = TimeEnergyUseInfoDTO.sumAll(energyId, energyData);
        info.setUse(sum);
        list.add(info);
        return list;
    }

    private List<IndexEnergyMapSubjectVO.Info> getByInstitutionId(DateTypeEnum source, Long instituteId, Long energyId, Date from, String acceptLanguage) {
        List<InstituteInfoDO> children = instituteInfoManager
                .getAllMap()
                .values()
                .stream()
                .filter(i -> instituteId.equals(i.getParentId()))
                .sorted(Comparator.comparing(InstituteInfoDO::getId))
                .collect(Collectors.toList());
        List<IndexEnergyMapSubjectVO.Info> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(children)) {
            for (InstituteInfoDO child : children) {
                IndexEnergyMapSubjectVO.Info info = new IndexEnergyMapSubjectVO.Info();
                if (StringUtils.hasLength(child.getSatelliteLocation())) {
                    info.setLocation(EmsUtil.formatLocation(child.getSatelliteLocation()));
                }
                info.setName(EmsUtil.getNameInfo(child.getNameInfo(), acceptLanguage).getShortName());
                info.setSubjectId(child.getId());
                info.setSubjectType(SubjectTypeEnum.INSTITUTE.name());
                List<Long> meterIds = getEnergyMeterIdsByInstitutionId(child.getId());
                List<Long> pointIds = getCumulatePointIds(meterIds, energyId, null, null, null);
                List<QueryPointEnergyResultDTO> energyData = getPointEnergy(source, from, new Date(), pointIds);
                TimeEnergyUseInfoDTO sum = TimeEnergyUseInfoDTO.sumAll(energyId, energyData);
                info.setUse(sum);
                list.add(info);
            }
            return list;
        }
        List<BuildingInfoDO> buildings = buildingInfoManager
                .getAllMap()
                .values()
                .stream()
                .filter(b -> instituteId.equals(b.getInstituteId())).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(buildings)) {
            for (BuildingInfoDO building : buildings) {
                IndexEnergyMapSubjectVO.Info info = new IndexEnergyMapSubjectVO.Info();
                if (StringUtils.hasLength(building.getSatelliteLocation())) {
                    info.setLocation(EmsUtil.formatLocation(building.getSatelliteLocation()));
                }
                info.setName(EmsUtil.getNameInfo(building.getNameInfo(), acceptLanguage).getShortName());
                info.setSubjectId(building.getId());
                info.setSubjectType(SubjectTypeEnum.BUILDING.name());
                List<Long> meterIds = getEnergyMeterIdsByBuildingId(building.getId());
                List<Long> pointIds = getCumulatePointIds(meterIds, energyId, null, null, null);
                List<QueryPointEnergyResultDTO> energyData = getPointEnergy(source, from, new Date(), pointIds);
                TimeEnergyUseInfoDTO sum = TimeEnergyUseInfoDTO.sumAll(energyId, energyData);
                info.setUse(sum);
                list.add(info);
            }
            return list;
        }
        InstituteInfoDO instituteInfo = instituteInfoManager.getAllMap().get(instituteId);
        IndexEnergyMapSubjectVO.Info info = new IndexEnergyMapSubjectVO.Info();
        if (StringUtils.hasLength(instituteInfo.getSatelliteLocation())) {
            info.setLocation(EmsUtil.formatLocation(instituteInfo.getSatelliteLocation()));
        }
        info.setName(EmsUtil.getNameInfo(instituteInfo.getNameInfo(), acceptLanguage).getShortName());
        info.setSubjectId(instituteInfo.getId());
        info.setSubjectType(SubjectTypeEnum.INSTITUTE.name());
        List<Long> meterIds = getEnergyMeterIdsByInstitutionId(instituteInfo.getId());
        List<Long> pointIds = getCumulatePointIds(meterIds, energyId, null, null, null);
        List<QueryPointEnergyResultDTO> energyData = getPointEnergy(source, from, new Date(), pointIds);
        TimeEnergyUseInfoDTO sum = TimeEnergyUseInfoDTO.sumAll(energyId, energyData);
        info.setUse(sum);
        list.add(info);
        return list;
    }
}
